#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include "common.h"

/*PE3 --> 16; PE2 --> 15*/
#define RGB_SCL_PIN     16
#define RGB_SDA_PIN     15
#define RGB_EN_PIN      10

#define SCL_LOW()     rt_pin_write(RGB_SCL_PIN,PIN_LOW)
#define SCL_HIGH()    rt_pin_write(RGB_SCL_PIN,PIN_HIGH) 

#define SDA_LOW()     rt_pin_write(RGB_SDA_PIN,PIN_LOW)
#define SDA_HIGH()    rt_pin_write(RGB_SDA_PIN,PIN_HIGH) 

/*底板AB32 RGB led 测试*/
void board_led_test()
{
    uint8_t led_red_pin = rt_pin_get("PE.1");
    uint8_t led_blue_pin = rt_pin_get("PA.1");
    uint8_t led_green_pin = rt_pin_get("PE.4");

    rt_pin_mode(led_red_pin, PIN_MODE_OUTPUT);
    rt_pin_mode(led_blue_pin, PIN_MODE_OUTPUT);
    rt_pin_mode(led_green_pin, PIN_MODE_OUTPUT);
    while(1)
    {
        rt_pin_write(led_red_pin, PIN_LOW);
        rt_thread_mdelay(200);
        rt_pin_write(led_green_pin, PIN_HIGH);
        rt_thread_mdelay(200);
        rt_pin_write(led_blue_pin, PIN_LOW);
        rt_thread_mdelay(200);
        rt_pin_write(led_red_pin, PIN_HIGH);
        rt_thread_mdelay(200);
        rt_pin_write(led_green_pin, PIN_LOW);
        rt_thread_mdelay(200);
        rt_pin_write(led_blue_pin, PIN_HIGH);
        rt_thread_mdelay(200);
        rt_kprintf("rt-thread tick: %d \n",rt_tick_get());
    }
}

/*Gokit 驱动板 RGB LED 灯 */
void RGBLED_delay()
{
    rt_hw_us_delay(2);
}

//发送前32位'0'起始帧
void RGBLED_Send32Zero(void)
{
	 uint8_t i;
	
	 SDA_LOW();
	 for(i = 0; i < 32; i++)
	 {
	    SCL_LOW();
        RGBLED_delay();
        SCL_HIGH();
        RGBLED_delay();		
	 } 
}

//反转前两位的灰度值
uint8_t RGBLED_TakeAntiCode(uint8_t dat)
{
	 uint8_t tmp = 0;
	
	 tmp = ((~dat) & 0xC0) >> 6;
	 return tmp;
}

//发送灰度数据
void RGBLED_DatSend(uint32_t dx)
{
	 uint8_t i;
	 
	 for(i=0;i<32;i++)
	 {
		if((dx & 0x80000000) !=0)
		    SDA_HIGH();
		else 
	        SDA_LOW();	
		dx<<=1;
		SCL_LOW();
        RGBLED_delay();
		SCL_HIGH();
        RGBLED_delay();
	 }	
}

//数据处理与发送
//r;红色值 0~255
//g:绿色值 0~255
//b:蓝色值 0~255
void RGBLED_DataDealWithAndSend(uint8_t r,uint8_t g,uint8_t b)
{ 
	 uint32_t dx=0;
	
	 dx |= (uint32_t)0x03 << 30;  //前两位'1'位标志位
	 dx |= (uint32_t)RGBLED_TakeAntiCode(b) << 28;
	 dx |= (uint32_t)RGBLED_TakeAntiCode(g) << 26;
	 dx |= (uint32_t)RGBLED_TakeAntiCode(r) << 24;
	 dx |= (uint32_t)b << 16;
	 dx |= (uint32_t)g << 8;
	 dx |= r;
	
	 RGBLED_DatSend(dx);//发送数据
}

//RGB灯控制函数
//r;红色值 0~255
//g:绿色值 0~255
//b:蓝色值 0~255
void LED_RGB_Control(uint8_t r,uint8_t g,uint8_t b)
{
    RGBLED_Send32Zero();//发送前32位'0'起始帧
    RGBLED_DataDealWithAndSend(r, g, b);//发送32bit灰度数据
    RGBLED_DataDealWithAndSend(r, g, b);
}

//颜色值
#define Red    1   //红色
#define Green  2   //绿色
#define Blue   3   //蓝色
#define Yellow 4   //黄色
#define Purple 5   //紫色
#define Pink   6   //粉色

#define PWM_DEV_NAME        "lpwm0"  /* PWM设备名称 */
#define PWM_DEV_CHANNEL     0       /* PWM通道 */

struct rt_device_pwm *pwm_dev;      /* PWM设备句柄 */

static void pwm_led_init()
{
    /* 查找设备 */
    pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME);
    if (pwm_dev == RT_NULL)
    {
        rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME);
        return RT_ERROR;
    }

    /* 设置PWM周期和脉冲宽度默认值 */
    rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, 2000, 0);
    /* 使能设备 */
    rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);
//    rt_pwm_disable(pwm_dev, PWM_DEV_CHANNEL);
}

void GoKit_RGB_led_Init()
{
    rt_pin_mode(RGB_EN_PIN, PIN_MODE_OUTPUT);

    rt_pin_mode(RGB_SDA_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(RGB_SCL_PIN, PIN_MODE_OUTPUT);

    rt_pin_write(RGB_EN_PIN, PIN_HIGH);
    rt_pin_write(RGB_SCL_PIN, PIN_HIGH);
    rt_pin_write(RGB_SDA_PIN, PIN_HIGH);

    LED_RGB_Control(0, 0, 0);
    pwm_led_init();
}

void Update_RGB_led_Status()
{
    LED_RGB_Control(s_m_current_data.led_red,s_m_current_data.led_green,s_m_current_data.led_blue);
    if(s_m_current_data.light == 0)
        rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, 2000, 0);
    else 
        rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, 2000, 1000);
}


